package cc.linker.steplink.crm.merchant.service;

import cc.linker.steplink.crm.commons.constant.ContentConstant;
import cc.linker.steplink.crm.commons.constant.WcPayConstant;
import cc.linker.steplink.crm.commons.http.HttpService;
import cc.linker.steplink.crm.commons.model.SystemProperties;
import cc.linker.steplink.crm.merchant.dao.WxDao;
import cc.linker.steplink.crm.merchant.dao.acs.MerchantInfoDao;
import cc.linker.steplink.crm.response.GlobalException;
import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.mongodb.util.JSON;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.io.IOException;
import java.math.BigDecimal;
import java.net.URISyntaxException;
import java.text.SimpleDateFormat;
import java.util.*;

import static cc.linker.steplink.crm.merchanth5.controller.OverViewInfoController.*;

@Slf4j
@Service
public class WxService {


    @Autowired
    private WxDao wxDao;
    @Autowired
    private MerchantInfoDao merchantInfoDao;
    @Autowired
    private StringRedisTemplate redisTemplate;
    @Autowired
    private SystemProperties systemProperties;
    @Autowired
    private HttpService httpService;

    public String getToken(String orgId) {
        return wxDao.getToken(orgId);
    }

    public String getTokenByAppId(String appId) {
        return wxDao.getTokenByAppId(appId);
    }

    public Map<String, Object> overview(String orgId, String adminId, Boolean ifSales) {
        String customerId = merchantInfoDao.getCustomerIdByAdminId(adminId);
        // 机构下数据
        Map<String, Object> overView;
        if (ifSales) {
            overView = wxDao.getOverViewByOrgId(orgId);
        } else {
            overView = wxDao.getOverViewByOrgIdAndCustomerId(orgId, customerId);
        }
        if (overView == null) {
            overView = new HashMap<>();
            overView.put("guestYesterday", 0);
            overView.put("newSubscribeYesterday", 0);
            overView.put("pageExposureYesterday", 0);
            overView.put("goodsExposureYesterday", 0);
            overView.put("activityYesterday", 0);
        }
        Long guest = redisTemplate.opsForSet().size(GUEST + orgId);
        String newSubscribe = (String) redisTemplate.opsForHash().get(NEW_SUBSCRIBE, orgId);
        String pageExposure = (String) redisTemplate.opsForHash().get(PAGE_EXPOSURE, orgId);
        String goodsExposure = (String) redisTemplate.opsForHash().get(GOODS_EXPOSURE, ifSales ? customerId : orgId);
        String activity = wxDao.getActivityNowByOrgId(orgId);
        activity = new BigDecimal(activity).setScale(2, BigDecimal.ROUND_HALF_EVEN).toString();
        overView.put("guest", guest);
        overView.put("newSubscribe", newSubscribe);
        overView.put("pageExposure", pageExposure);
        overView.put("goodsExposure", goodsExposure);
        overView.put("activity", activity);
        Integer refund;
        Integer refundYesterday;
        if (ifSales) {
            // 小b
            Map<String, Object> incoming = wxDao.getIncomingByReceiveUser(customerId,orgId);//商品
            Map<String, Object> incomingEnroll = wxDao.getIncomingEnrollByReceiveUser(customerId,orgId);//报名
            incoming.put("incoming", ((BigDecimal) incoming.get("incoming")).add((BigDecimal) incomingEnroll.get("incoming")));
            incoming.put("incomingYesterday", ((BigDecimal) incoming.get("incomingYesterday")).add((BigDecimal) incomingEnroll.get("incomingYesterday")));
            overView.putAll(incoming);


            Map<String, Object> payCount = wxDao.getPayCountByReceiveUser(customerId,orgId);//商品
//            Map<String, Object> payCountEnroll = wxDao.getPayCountEnrollByReceiveUser(customerId,orgId);//报名
            Map<String, Object> payCountForm = wxDao.getPayCountFormByReceiveUser(customerId,orgId);//表单
            int goodsPayCount = Integer.valueOf(payCount.get("payCount").toString());
            int enrollPayCount = Integer.valueOf(payCountForm.get("payCount").toString());
            payCount.put("payCount",goodsPayCount+enrollPayCount);
            int goodsPayCountYesterday = Integer.valueOf(payCount.get("payCountYesterday").toString());
            int enrollPayCountYesterday = Integer.valueOf(payCountForm.get("payCountYesterday").toString());
            payCount.put("payCountYesterday",goodsPayCountYesterday+enrollPayCountYesterday);
            overView.putAll(payCount);


            refund = wxDao.countRefundByCustomerId(customerId, orgId);
            refundYesterday = wxDao.countYesterdayRefundByCustomerId(customerId, orgId);
        } else {
            // 大b
            Map<String, Object> incoming = wxDao.getIncomingByReceiveUser("",orgId);//商品
            Map<String, Object> incomingKt = wxDao.getIncomingKtByReceiveUser("",orgId);//开通
            Map<String, Object> incomingEnroll = wxDao.getIncomingEnrollByReceiveUser(orgId,orgId);//报名
//            Map<String, Object> incomingVip = wxDao.getIncomingVipByReceiveUser("",orgId);//VIP
            incoming.put("incoming", ((BigDecimal) incoming.get("incoming")).add((BigDecimal) incomingKt.get("incoming")).add((BigDecimal) incomingEnroll.get("incoming")));
            incoming.put("incomingYesterday", ((BigDecimal) incoming.get("incomingYesterday")).add((BigDecimal) incomingKt.get("incomingYesterday")).add((BigDecimal) incomingEnroll.get("incomingYesterday")));
            overView.putAll(incoming);

            Map<String, Object> payCount = wxDao.getPayCountByReceiveUser("",orgId);//商品
            Map<String, Object> payCountEnroll = wxDao.getPayCountFormByReceiveUser(orgId,orgId);//表单
//            Map<String, Object> payCountEnroll = wxDao.getPayCountEnrollByReceiveUser(orgId,orgId);//报名
            Map<String, Object> payCountKt = wxDao.getPayCountKtByReceiveUser("",orgId);//开通
            Map<String, Object> vipCountKt = wxDao.getPayCountVipByReceiveUser("",orgId);//VIP
            payCount.put("payCount",Integer.valueOf(payCount.get("payCount").toString())+Integer.valueOf(payCountEnroll.get("payCount").toString())+Integer.valueOf(payCountKt.get("payCount").toString())+Integer.valueOf(vipCountKt.get("payCount").toString()));
            payCount.put("payCountYesterday",Integer.valueOf(payCount.get("payCountYesterday").toString())+Integer.valueOf(payCountEnroll.get("payCountYesterday").toString())+Integer.valueOf(payCountKt.get("payCountYesterday").toString())+Integer.valueOf(vipCountKt.get("payCountYesterday").toString()));
            overView.putAll(payCount);

            refund = wxDao.countRefundByCustomerId("", orgId);
            refundYesterday = wxDao.countYesterdayRefundByCustomerId("", orgId);
        }
        overView.put("refund",refund);
        overView.put("refundYesterday",refundYesterday);
        BigDecimal incoming = (BigDecimal) overView.get("incoming");
        String incomingStr = new BigDecimal(incoming.doubleValue() / 100).setScale(2, BigDecimal.ROUND_HALF_EVEN).toString();
        BigDecimal incomingYesterday = (BigDecimal) overView.get("incomingYesterday");
        if (incomingYesterday == null) {
            incomingYesterday = new BigDecimal(0);
        }
        String incomingYesterdayStr = new BigDecimal(incomingYesterday.doubleValue() / 100).setScale(2, BigDecimal.ROUND_HALF_EVEN).toString();
        overView.put("incoming", incomingStr + "元");
        overView.put("incomingYesterday", incomingYesterdayStr + "元");

        String activity1 = new BigDecimal(overView.get("activity").toString()).multiply(new BigDecimal(100)).setScale(0).toString() + "%";
        String activity2 = new BigDecimal(overView.get("activityYesterday").toString()).multiply(new BigDecimal(100)).setScale(0).toString() + "%";
        overView.put("activity", activity1);
        overView.put("activityYesterday", activity2);

        Set<String> keys = redisTemplate.keys(INTERACTION + orgId + "_*");
        if (null == keys) {
            keys = new HashSet<>();
        }
        overView.put("interaction", keys.size());

        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.DATE, -1);
        Date startDate = calendar.getTime();

        Calendar calendar2 = Calendar.getInstance();
        calendar2.add(Calendar.DATE, -31);
        Date endDate = calendar2.getTime();

        List<String> dates = findDates(endDate, startDate);
        Set<String> result = new HashSet<>();
        for(String dayStr:dates){
            Set<String> members = redisTemplate.opsForSet().members(INTERACTION + dayStr + "_" + orgId);
            if(null != members && members.size()>0){
                result.addAll(members);
            }
        }
        overView.put("interactionYesterday", result.size());

        return overView;
    }

    public Map<String, Object> smart(String orgId, String adminId, Boolean ifSales) {
        Map<String, Object> result = new HashMap<>();
        Map<String, Object> platform = new HashMap<>();
        Map<String, Object> mall = new HashMap<>();
        Map<String, Object> mallImportant = new HashMap<>();
        Map<String, Object> mallSecondary = new HashMap<>();
        Map<String, Object> order = new HashMap<>();
        Map<String, Object> orderImportant = new HashMap<>();
        if (ifSales) {
            // 小b
            String customerId = merchantInfoDao.getCustomerIdByAdminId(adminId);
            // 商家认证
            Integer certification = wxDao.countCertificationByCustomerId(customerId);
            mallImportant.put("certification", certification > 0 ? 1 : 0);
            // 商品发布
            Integer goods = wxDao.countGoodsByCustomerId(customerId);
            mallSecondary.put("goods", goods > 0 ? 1 : 0);
            // 商家联系方式配置，商品退货信息配置
            Map<String, Object> merchantInfo = wxDao.countMerchantInfoByCustomerId(customerId);
            if (merchantInfo == null) {
                merchantInfo = new HashMap<>();
                merchantInfo.put("contact", 0);
                merchantInfo.put("return", 0);
            }
            mallSecondary.putAll(merchantInfo);
            // 待发货
            Integer delivered = wxDao.countDeliveredByCustomerId(customerId);
            orderImportant.put("delivered", delivered);
            Integer refund = wxDao.countRefundByCustomerId(customerId, orgId);
            orderImportant.put("refund", refund);
        } else {
            // 大b
            Map<String, Object> platformImportant = new HashMap<>();
            String token = wxDao.getToken(orgId);
            // 公众号绑定
            platformImportant.put("public", StringUtils.isEmpty(token) ? 0 : 1);
            // todo 春哥接口 公众号业务域名配置
            platformImportant.put("domain", StringUtils.isEmpty(token) ? 0 : 1);
            // 内容库接口 公众号一次性订阅消息配置
            String contentUrl = systemProperties.getSync().getContentUrl() + ContentConstant.PUBLIC_GET_TEMPLATE_ID_BY_ORG;
            Map<String, Object> reqMap = new HashMap<>();
            reqMap.put("organizationNum", orgId);
            String template = "";
            try {
                template = httpService.doPost(contentUrl, reqMap, ContentConstant.HEADER);
            } catch (URISyntaxException | IOException e) {
                LOGGER.error("调用内容库接口异常");
            }
            try {
                Map parse = (Map) JSONObject.parse(template);
                Map data = (Map) parse.get("data");
                boolean falg = (boolean) data.get("falg");
                platformImportant.put("subscription", falg ? 1 : 0);
            } catch (Exception e) {
                LOGGER.error("智能助手内容库结果异常");
                platformImportant.put("subscription", 0);
            }
            Map<String, Object> platformSecondary = new HashMap<>();
            // 标签
            Integer label = wxDao.countLabelByOrgId(orgId);
            platformSecondary.put("label", label > 0 ? 1 : 0);
            // 等级
            Integer level = wxDao.countLevelByOrgId(orgId);
            platformSecondary.put("level", level > 0 ? 1 : 0);
            // 积分活动
            Integer active = wxDao.countActiveByOrgId(orgId);
            platformSecondary.put("active", active > 0 ? 1 : 0);
            // 分群
            Integer group = wxDao.countGroupByOrgId(orgId);
            platformSecondary.put("group", group > 0 ? 1 : 0);
            platform.put("important", platformImportant);
            platform.put("secondary", platformSecondary);


            // 商家认证
            Integer certification = wxDao.countCertificationByOrgId(orgId);
            mallImportant.put("certification", certification > 0 ? 1 : 0);
            // 支付配置
            Integer payment = wxDao.countPaymentByOrgId(orgId);
            mallImportant.put("payment", payment > 0 ? 1 : 0);
            // 商品发布
            Integer goods = wxDao.countGoodsByOrgId(orgId);
            mallSecondary.put("goods", goods > 0 ? 1 : 0);
            // 商家联系方式配置，商品退货信息配置
            Map<String, Object> merchantInfo = wxDao.countMerchantInfoByOrgId(orgId);
            if (merchantInfo == null) {
                merchantInfo = new HashMap<>();
                merchantInfo.put("contact", 0);
                merchantInfo.put("return", 0);
            }
            mallSecondary.putAll(merchantInfo);

            // 待发货
            Integer delivered = wxDao.countDeliveredByOrgId(orgId);
            orderImportant.put("delivered", delivered);
            Integer refund = wxDao.countRefundByCustomerId("", orgId);
            orderImportant.put("refund", refund);
        }
        result.put("platform", platform);

        mall.put("important", mallImportant);
        mall.put("secondary", mallSecondary);
        result.put("mall", mall);

        order.put("important", orderImportant);
        result.put("order", order);

        return result;
    }


    public PageInfo dynamic(String orgId, Integer pageIndex, Integer pageSize) {
        PageHelper.startPage(pageIndex, pageSize);
        List<Map<String, Object>> mapList = wxDao.listDynamicByOrgId(orgId);
        mapList.forEach(x -> {
            String headSculpture = (String) x.get("headSculpture");
            if (!StringUtils.isEmpty(headSculpture)) {
                String s = systemProperties.getAvatarAddress() + headSculpture;
                x.put("headSculpture", s);
            }
        });
        return new PageInfo<>(mapList);
    }

    public void entrydel(Map<String, Object> params) {
        this.callUserCenter(params, "/general/entrydel", 2);
    }

    public Object allmenu(Map<String, Object> params) {
        return this.callUserCenter(params, "/general/allmenu", 1);
    }

    public Object menuentry(Map<String, Object> params) {
        return this.callUserCenter(params, "/general/menuentry", 1);
    }

    public void entryset(Map<String, Object> params) {
        this.callUserCenter(params, "/general/entryset", 2);
    }

    /**
     * 调用用户中心通用api接口
     *
     * @param params 参数
     * @param method 接口地址
     * @param type   1-get 2-post
     * @return
     */
    public Object callUserCenter(Map<String, Object> params, String method, int type) {
        String url = systemProperties.getManageweb() + "/UserWebApi/api" + method;
        try {
            String result;
            if (type == 1) {
                result = httpService.doGet(url, params);
            } else if (type == 2) {
                result = httpService.doPost(url, JSON.serialize(params), WcPayConstant.JSON);
            } else {
                throw GlobalException.build("");
            }
//        LOGGER.info("WxService.callUserCenter===" + result);
            Map parse = (Map) JSON.parse(result);
            Integer retcode = (Integer) parse.get("retcode");
            if (retcode != null && retcode == 0) {
                if (type == 1) {
                    return parse.get("retobj");
                } else {
                    return null;
                }
            } else {
                throw GlobalException.build("");
            }
        } catch (Exception e) {
            throw GlobalException.build("用户中心接口调用异常");
        }
    }


    public static List<String> findDates(Date dBegin, Date dEnd) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        List<String> lDate = new ArrayList<>();
        lDate.add(sdf.format(dBegin));
        Calendar calBegin = Calendar.getInstance();
        // 使用给定的 Date 设置此 Calendar 的时间
        calBegin.setTime(dBegin);
        Calendar calEnd = Calendar.getInstance();
        // 使用给定的 Date 设置此 Calendar 的时间
        calEnd.setTime(dEnd);
        // 测试此日期是否在指定日期之后
        while (dEnd.after(calBegin.getTime())) {
            // 根据日历的规则，为给定的日历字段添加或减去指定的时间量
            calBegin.add(Calendar.DAY_OF_MONTH, 1);
            String strDate = sdf.format(calBegin.getTime());
            lDate.add(strDate);
        }
        return lDate;
    }
}
